﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace T.FAS.Runtime.Base.Entity
{
    public class ViewModelDataBuilder
    {
        /// <summary>
        /// 构造viewmodel数据集合
        /// </summary>
        /// <param name="ds">数据集合</param>
        /// <param name="schema">viewmodel结构</param>
        /// <returns></returns>
        public JToken BuildViewModelData(DataSet ds, ViewModelSchema schema)
        {
            if (ds == null || ds.Tables == null || ds.Tables.Count <= 0)
                throw new ArgumentNullException("ViewModelDataBuilder.BuildViewModelData Error,DS is null");
            if (schema == null || schema.Current == null || schema.Current.Count <= 0)
                throw new ArgumentNullException("ViewModelDataBuilder.BuildViewModelData Error,shcema is null");
            if (schema.Current.Count == 1)
                return BuildViewModelItemData(ds, schema.Current[0].ViewModelItemSchema, "", false);
            else
            {
                var result = new JArray();
                schema.Current.ForEach(item=>
                {
                    var JResult = BuildViewModelItemData(ds, item.ViewModelItemSchema, "", true);
                    result.Add(JResult);
                });
                return result;
            }
        }
        /// <summary>
        /// 构造viewmodelitem数据集合
        /// </summary>
        /// <param name="ds">数据集合</param>
        /// <param name="vmis">viewmodelitem结构</param>
        /// <param name="parentData">关联数据</param>
        /// <param name="isList">是否列表</param>
        /// <param name="isRelated">是否是数据关联</param>
        /// <returns></returns>
        private JToken BuildViewModelItemData(DataSet ds, ViewModelItemSchema vmis, string relatedData = "", bool isList = false, bool isRelated = false)
        {
            JToken jResult = default;
            var dt = ds.Tables[vmis.ViewModelItemCode];
            if (dt != null && dt.Rows != null && dt.Rows.Count > 0)
            {
                if (!isRelated)
                {
                    if (dt.Rows.Count > 1)
                    {
                        jResult = new JArray();
                        isList = true;
                    }
                    else
                    {
                        if (isList)
                            jResult = new JArray();
                        else
                            jResult = new JObject();
                    }
                }
                else
                {
                    if (isList)
                        jResult = new JArray();
                    else
                        jResult = new JObject();

                }
                foreach (DataRow row in dt.Rows)
                {
                    var obj = new JObject();
                    if (isRelated && !string.IsNullOrEmpty(relatedData))
                    {
                        if (vmis.Relation == null)
                            break;
                        var primaryKeyProp = vmis.Properties.Find(x => x.Code.Equals(vmis.Relation.ToPropertyCode));
                        if (primaryKeyProp == null)
                            break;
                        if (!row[primaryKeyProp.Code].Equals(relatedData))
                            continue;
                    }
                    vmis.Properties.ForEach(p =>
                    {
                        if (!p.IsVirtual && obj.Property(p.Code) ==null)
                        {
                            if (p.DataType == DataType.List)
                            {
                                obj.Add(new JProperty(p.Code, BuildViewModelItemData(ds, p.SubSchema, Convert.ToString(row[p.RelatePropertyCode]), true, true)));
                            }
                            else if (p.DataType == DataType.Record)
                            {
                                obj.Add(new JProperty(p.Code, BuildViewModelItemData(ds, p.SubSchema, Convert.ToString(row[p.RelatePropertyCode]), false, true)));
                            }
                            else
                            {
                                obj.Add(new JProperty(p.Code, Convert.ChangeType(row[p.Code], ViewModelDataTypeHelper.ConvertDataType(p.DataType))));
                            }
                        }
                    });
                    if (isList)
                        (jResult as JArray).Add(obj);
                    else
                        jResult = obj;
                }
            }
            return jResult;
        }
    }
}
